package com.ebrg.secure9.activity.setup;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.text.InputType;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.ebrg.secure9.Account;
import com.ebrg.secure9.Preferences;
import com.ebrg.secure9.activity.K9Activity;
import com.ebrg.secure9.activity.MessageList;
import com.ebrg.secure9.mail.Address;
import com.ebrg.secure9.mail.security.Hash;
import com.ebrg.secure9.R;


public class EncryptionPin extends K9Activity implements OnClickListener{
	private Account mAccount;
	private static final String EXTRA_ACCOUNT = "account";
	private EditText firstPin;
	private EditText confirmPin;
	private Button nextButton;
	private Button deleteButton;
	public static String remoteEmailSource;
	public static Address[] otherParty;
	private static TextView pinStatus;

	public static String original;
	public static int randomSaltLength;

	public static void actionNewPin(Activity context, Account account)
	{

		Intent i = new Intent(context, EncryptionPin.class);
		i.setAction(Intent.ACTION_EDIT);
		i.putExtra("account", account.getUuid());
		context.startActivity(i);

	}

	//Create and save hashed pin.  
	private void onNext()
	{
		char[] inputPin1 = new char[firstPin.getText().length()];
		for(int i = 0; i < firstPin.getText().length(); i++)
			inputPin1[i] = firstPin.getText().charAt(i);

		
		char[] inputPin2 = new char[confirmPin.getText().length()];
		for(int i = 0; i < confirmPin.getText().length(); i++)
			inputPin2[i] = confirmPin.getText().charAt(i);
		
		
		String FILENAME1 = (mAccount.getEmail().toString()  + this.getString(R.string.hashed_pin_file_type)).toLowerCase();
		if(!Arrays.equals(inputPin1, inputPin2))
		{
			Toast.makeText(EncryptionPin.this, "PINs to not match!", Toast.LENGTH_SHORT).show();
			return;
		}
		
		else if(inputPin1.length < 4)
		{
			Toast.makeText(EncryptionPin.this, R.string.pin_too_short, Toast.LENGTH_SHORT).show();
			return;
		}
		
		else if(pinStatus.getText().equals("PIN is currently disabled and not linked to this account"))
		{
			try 
			{	
				//save .pin2
				String hash  = Hash.setHash(mAccount.getEmail().toString(), inputPin1, 
						EncryptionPin.this);

				FileOutputStream fos1 = openFileOutput(FILENAME1, Context.MODE_PRIVATE);
				fos1.write(hash.getBytes());
				fos1.close();
				//Alert user that process is completed, then return to settings page.
				Toast.makeText(EncryptionPin.this, "Hash saved successfully", Toast.LENGTH_SHORT).show();

				//Hide keyboard
				((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE))  
				.hideSoftInputFromWindow(confirmPin.getWindowToken(), 0); 
			} catch (FileNotFoundException e) {
				// TODO Auto-generated catch block
				Log.v("Fie not found", e.getLocalizedMessage());
			} catch (IOException e) {
				// TODO Auto-generated catch block
				Log.v("IO Exception",e.getLocalizedMessage());
			}
		
			redraw();	
			MessageList.actionHandleFolder(this, mAccount, mAccount.getAutoExpandFolderName());
			finish();

		}
		
		else if(firstPin.getText().toString().equals(confirmPin.getText().toString())
				&& pinStatus.getText().equals("PIN is enabled and linked to this account"))
			Toast.makeText(EncryptionPin.this, "PIN already configured.  Remove current pin and create a new one to change.", Toast.LENGTH_LONG).show();
	}

	//Redraw screen once pin delete or create has been performed
	private void redraw()
	{
		//Check for pin file	
		if(Hash.pinExists(this, mAccount.getEmail().toLowerCase()))
		{
			pinStatus.setText("PIN is enabled and linked to this account");
			pinStatus.setTextColor(Color.GREEN); 
			firstPin.setEnabled(false);
			firstPin.setFocusable(false);
			confirmPin.setEnabled(false);
			confirmPin.setFocusable(false);

		}
		else
		{
			pinStatus.setText("PIN is currently disabled and not linked to this account");
			pinStatus.setTextColor(Color.RED);
			firstPin.setEnabled(true);
			firstPin.setFocusable(true);
			firstPin.setText("");
			firstPin.setFocusableInTouchMode(true);
			confirmPin.setEnabled(true);
			confirmPin.setFocusable(true);
			confirmPin.setFocusableInTouchMode(true);
			confirmPin.setText("");
		}
	}
	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);
		String accountUuid = getIntent().getStringExtra("account");
		mAccount = Preferences.getPreferences(this).getAccount(accountUuid);

		setContentView(R.layout.encryption_pin);
		this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN); 

		if (savedInstanceState != null && savedInstanceState.containsKey(EXTRA_ACCOUNT))
		{
			accountUuid = savedInstanceState.getString(EXTRA_ACCOUNT);
			mAccount = Preferences.getPreferences(this).getAccount(accountUuid);
		}

		pinStatus = (TextView)findViewById(R.id.pin_status);
		firstPin = (EditText)findViewById(R.id.pin);
		firstPin.setInputType(InputType.TYPE_CLASS_PHONE);
		firstPin.setTransformationMethod
		(android.text.method.PasswordTransformationMethod.getInstance());

		confirmPin = (EditText)findViewById(R.id.confirm_pin);
		confirmPin.setInputType(InputType.TYPE_CLASS_PHONE);
		confirmPin.setTransformationMethod
		(android.text.method.PasswordTransformationMethod.getInstance());

		nextButton = (Button)findViewById(R.id.next);
		nextButton.setOnClickListener(this);
		nextButton.setEnabled(true);

		deleteButton = (Button)findViewById(R.id.delete_pin);
		deleteButton.setOnClickListener(this);
		deleteButton.setEnabled(false);
		
		//If pin exists, enable delete button and disable next button
		if(Hash.pinExists(this, mAccount.getEmail()))
		{
			nextButton.setEnabled(false);
			deleteButton.setEnabled(true);
		}
		redraw();
	}

	@Override
	public void onResume()
	{
		super.onResume();
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event)
	{
		return super.onKeyDown(keyCode, event);
	}

	@Override
	public void onSaveInstanceState(Bundle outState)
	{
		super.onSaveInstanceState(outState);
		outState.putSerializable(EXTRA_ACCOUNT, mAccount.getUuid());
	}

	public void onClick(View v)
	{
		switch (v.getId())
		{
		case R.id.next:			
			onNext();			
			break;
		case R.id.delete_pin:	
			deletePin();
			break;
		}
	}


	//Delete account pin file
	private void deletePin()
	{
		if(Hash.pinExists(this, mAccount.getEmail().toLowerCase()))
		{
			AlertDialog.Builder alert = new AlertDialog.Builder(this);
			alert.setTitle("Confirm PIN");
			alert.setMessage("Enter your PIN to unlink it from this account");

			// Set an EditText view to get user input 
			final EditText input = new EditText(this);
			input.setInputType(InputType.TYPE_CLASS_PHONE);
			input.setTransformationMethod

			(android.text.method.PasswordTransformationMethod.getInstance());
			alert.setView(input);

			alert.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int whichButton) {
					if(input.getText().length() < 4)
					{
						Toast.makeText(EncryptionPin.this, R.string.pin_too_short, Toast.LENGTH_LONG).show();
						return;						
					}


					//Check .pin2
					FileInputStream fis1;
					try 
					{
						fis1 = openFileInput((mAccount.getEmail().toLowerCase()) + EncryptionPin.this.getString(R.string.hashed_pin_file_type));
						BufferedReader in1 = new BufferedReader(new InputStreamReader(fis1));	
						String test = in1.readLine();
						String storedHash = "";
						while(test != null)
						{
							storedHash = storedHash + test;
							test = in1.readLine();
						}

						
						char[] inputPin = new char[input.getText().length()];
						for(int i = 0; i < input.getText().length(); i++)
							inputPin[i] = input.getText().charAt(i);
											
						String storedStatic = Hash.getStatic(storedHash, input.getText().length(), EncryptionPin.this);
						String storedRand = Hash.getRandom(storedHash, input.getText().length(), EncryptionPin.this);						
						String userHash = Hash.verify(mAccount.getEmail().toString(), inputPin, storedRand, storedStatic);
						
						if(storedHash != null && userHash != null)
							if(Hash.compareHashes(storedHash, userHash))
							{
								Toast.makeText(EncryptionPin.this, "Hashes match. Pin deleted.", Toast.LENGTH_SHORT).show();

								EncryptionPin.this.deleteFile((mAccount.getEmail() + 
								EncryptionPin.this.getString(R.string.legacy_pin_file_type).toLowerCase()));	
								EncryptionPin.this.deleteFile((mAccount.getEmail() + 
								EncryptionPin.this.getString(R.string.hashed_pin_file_type).toLowerCase()));	

								mAccount.setAskForPin("Never");
								redraw();	
								MessageList.actionHandleFolder(EncryptionPin.this, mAccount, mAccount.getAutoExpandFolderName());
								finish();
							}
							else
								Toast.makeText(EncryptionPin.this, "Hash mismatch", Toast.LENGTH_SHORT).show();

					} catch (FileNotFoundException e) {
						Toast.makeText(EncryptionPin.this,"Hashed PIN not found",Toast.LENGTH_LONG).show();

					} catch (IOException e) {
						Toast.makeText(EncryptionPin.this,"Error retreiving PIN",Toast.LENGTH_SHORT).show();
					}
					
					char[] pinFromFile = new char[input.getText().length()];
					for(int i = 0; i < input.getText().length(); i++)
						pinFromFile[i] = input.getText().charAt(i);
					
					//Check .pin
					FileInputStream fis;
					try 
					{
						fis = openFileInput((mAccount.getEmail().toLowerCase()) + EncryptionPin.this.getString(R.string.legacy_pin_file_type));
						BufferedReader in = new BufferedReader(new InputStreamReader(fis));	
						char[] pin = in.readLine().toCharArray();

				     	if (Arrays.equals(pin, pinFromFile))
				     	{	
							mAccount.setAskForPin("0");
							EncryptionPin.this.deleteFile(mAccount.getEmail().toString().toLowerCase() + EncryptionPin.this.getString(R.string.legacy_pin_file_type));
							Toast.makeText(EncryptionPin.this, "PIN removed", Toast.LENGTH_SHORT).show();
							redraw();
							((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE))  
							.hideSoftInputFromWindow(input.getWindowToken(), 0); 

							mAccount.setAskForPin("Never");

							//Return to settings
							EncryptionSettings.encryptionSettings(EncryptionPin.this, mAccount);
						}

						else
							Toast.makeText(EncryptionPin.this, R.string.pin_incorrect, Toast.LENGTH_SHORT).show();

						if(pin != null)
							Arrays.fill(pin, '0');
						if(pinFromFile != null)
							Arrays.fill(pinFromFile, '0');

					} catch (FileNotFoundException e) {

					} catch (IOException e) {
					}



				} 

			});

			alert.setNegativeButton(R.string.cancel_action, new DialogInterface.OnClickListener() {
				public void onClick(DialogInterface dialog, int whichButton) {
					// Canceled.

				}
			});

			alert.setIcon(R.drawable.pin);
			alert.show();

		}
		else
			Toast.makeText(EncryptionPin.this,R.string.pin_not_found,Toast.LENGTH_SHORT).show();

	}
}
